feat!: Use artifactory catalog - #377
Conversation
| return nil, fmt.Errorf("sending request: %w", err) | ||
| } | ||
|
|
||
| if response.StatusCode < http.StatusOK || response.StatusCode >= http.StatusMultipleChoices { |
There was a problem hiding this comment.
Why not != http.StatusOK?
There was a problem hiding this comment.
well, since we are trying to make it generic, I thought we might want to accept 204 No Content and 206 Partial Content, and the caller would handle such. Can stick to != http.StatusOK if you think that's better?
There was a problem hiding this comment.
How would caller handle them right now?
There was a problem hiding this comment.
right now, they just check != http.StatusOK. Maybe you're right, and we won't need it. Will fix it to != http.StatusOK
|
Is |
| const ( | ||
| DefaultURL = "https://artifacts.tools.arm.com/devx-topo-project-catalog/" + version + "/catalog/" | ||
| DefaultCatalogURL = DefaultURL + "catalog.json" | ||
| DefaultSchemaURL = DefaultURL + "catalog.schema.json" |
There was a problem hiding this comment.
It feels a little unfortunate to download the schema for artifactory every time for every type of source. It means even users who use file:// sources require a network connection + slows the command down to download a static file every time.
Maybe fine for a v1 but wonder if we should consider downloading + embedding the schema version that the CLI supports into the binary? Especially since the catalogDocument type is a mirror of the schema.
Bonus - wonder if we should generate go types based on the schema?!
There was a problem hiding this comment.
Come to think of it, you’re right @awphi, this is a bit wasteful. I wonder if generating types based on the schema would be better. We could also do a pre-flight check of the $schema field in the received catalog - if it matches our expectation.
There was a problem hiding this comment.
yea I was thinking this on the way back home. For Bartek's suggestion, I'm not sure how that would alleviate user with file:// source from needing network connection? I think to address that, we have no choice but to keep the schema in the same repository
There was a problem hiding this comment.
Another thing we can try is to fetch the schema on release of topo, and embed that in the binary on release
ed774fc to
5b3f922
Compare
|
for error messages to precisely compare the versions, this PR needs to be merged first to continue - arm/topo-project-catalog#8 |
awphi
left a comment
There was a problem hiding this comment.
Nice! Have approved arm/topo-project-catalog#8 so we can add the major version check.
|
|
||
| compiler := jsonschema.NewCompiler() | ||
| schemaDoc, err := jsonschema.UnmarshalJSON(bytes.NewReader(catalogSchemaJSON)) | ||
| func parseProjects(ctx context.Context, b []byte) ([]Project, error) { |
| ```sh | ||
| go run ./scripts/generate_catalog_types v1 | ||
| ``` |
There was a problem hiding this comment.
Was //go generate not worth the trouble? I kind of like the idea of running all of our codebase dev tasks through standard go-supported paths if possible, not a blocker ofc
There was a problem hiding this comment.
if you like it, no problem using it. I was thinking if someone is not familiar with go generate, it's one less thing for them to read about if we keep it this way though. Basically does the same thing, but with directives, it's more looking up in the internet than just reading the code in my perspective
There was a problem hiding this comment.
On the flipside, it's nicer since you learn what go generate is once, then you can use it across any Go project rather than learning project-specific idioms like go run ./scripts/..., Makefiles, Justfiles or whatever people choose to use. My understanding is that's the whole point of go generate - standardisation.
|
|
||
| Topo uses the catalog version declared in `internal/catalog/catalog_schema_generated.go`. The same version selects both the catalog and its schema from Artifactory. | ||
|
|
||
| Generating the Go types requires Node.js 20 or newer, `npx`, and access to Artifactory. Pass the catalog version to the generator: |
There was a problem hiding this comment.
Is it worth calling out access to artifactory? It's public so anyone with an internet connection should have access right?
There was a problem hiding this comment.
yes. I'll get rid of this mention
| const ( | ||
| quicktypeVersion = "26.0.0" | ||
| defaultSchemaBaseURL = "https://artifacts.tools.arm.com/devx-topo-project-catalog/" | ||
| generationTimeout = 2 * time.Minute |
There was a problem hiding this comment.
Is a timeout strictly necessary? Think we can get away without it for an internal dev tool like this that does a pretty simple task
There was a problem hiding this comment.
good catch. I agree
| formatted, err := addCatalogVersionConstant(generated, catalogVersion) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to format quicktype output from schema %q: %w", schemaURL, err) | ||
| } | ||
| // #nosec G703 -- outputFile is derived from the generator source location. | ||
| if err := os.WriteFile(outputFile, formatted, 0o644); err != nil { | ||
| return fmt.Errorf("failed to write generated types to %q: %w", outputFile, err) | ||
| } |
There was a problem hiding this comment.
Is building an AST worth it here? Couldn't we just inject the const at the end of the file? e.g.
| formatted, err := addCatalogVersionConstant(generated, catalogVersion) | |
| if err != nil { | |
| return fmt.Errorf("failed to format quicktype output from schema %q: %w", schemaURL, err) | |
| } | |
| // #nosec G703 -- outputFile is derived from the generator source location. | |
| if err := os.WriteFile(outputFile, formatted, 0o644); err != nil { | |
| return fmt.Errorf("failed to write generated types to %q: %w", outputFile, err) | |
| } | |
| formatted := string(generated) + "\n" + "const CatalogMajorVersion = \"" + majorVersion(catalogVersion) + "\"\n" | |
| // #nosec G703 -- outputFile is derived from the generator source location. | |
| if err := os.WriteFile(outputFile, []byte(formatted), 0o644); err != nil { | |
| return fmt.Errorf("failed to write generated types to %q: %w", outputFile, err) | |
| } |
There was a problem hiding this comment.
I guess we can? it's just quite awkward to have const at the bottom in my instinct
There was a problem hiding this comment.
yea, I think we should judging by how much code we save
| func majorVersion(version string) string { | ||
| major, _, _ := strings.Cut(version, ".") | ||
| return major | ||
| } |
There was a problem hiding this comment.
It might be useful to store the full version in the const for us as maintainers if nothing else so we know what version of the schema a given version of the CLI uses without manually diffing our go types vs the source json schema.
There was a problem hiding this comment.
I agree. making this change now. Also we don't have the messge comparing the schema and the catalog version yet. making this as well
| // Advisory metadata that implementations may use to discover, filter, or suggest suitable | ||
| // parameter values. Unknown hint keys should be ignored. | ||
| type Hints struct { | ||
| } |
There was a problem hiding this comment.
Why has this been generated empty? Does quicktype not support patternProperties?
There was a problem hiding this comment.
oh good catch. It seems like patternProperties are not supported in quicktype. Does Hints need to be patternProperties?
Changes
Checklist